using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/// \class  gkComponentEnableDisableOnEvent
/// \brief  Enable and/or disable component on event
[AddComponentMenu("GK/Engine/GameCore/Component/gkComponentEnableDisableOnEvent")]
public class gkComponentEnableDisableOnEvent : MonoBehaviour 
{
	/// \brief  Choose the condition to enable/disable components
	/// Enable_Disable : Simply enable or disable component based on the received event
	/// Disable_ReEnable : Disable all the enabled controlledComponent and reEnable only those 
	/// Enable_ReDisable : Enable all the disabled controlledComponent and reDisable only those
	public enum EEnableDisableMode
	{
		Enable_Disable,
		Disable_ReEnable,
		Enable_ReDisable,
	};
	
	/// The enable disable mode
	public EEnableDisableMode EnableDisableMode;
		
	/// The controlled components
	public MonoBehaviour[] ControlledComponents;
	
	/// The deactivation event names
	public string[] DeactivateEventNames;
	
	/// The activation event names
	public string[] ActivateEventNames;
	
	/// The Hierarchy event component
	private gkEventComponent m_rEventComponent;
	
	/// The components to reEnable
	private List<MonoBehaviour> m_rToReEnableComponents = new List<MonoBehaviour>();
	
	/// The components to reDisable
	private List<MonoBehaviour> m_rToReDisableComponents = new List<MonoBehaviour>();
	
	/// \brief  Called when the component is enabled
	void OnEnable() 
	{			
		// Grab the event component of the hierarchy
		m_rEventComponent = transform.root.GetComponentInChildren<gkEventComponent>();
		
		// Listen the appear events of the owner
		foreach(string strEventName in DeactivateEventNames)
		{
			m_rEventComponent.AddEventHandler(strEventName, HandleDeactivationEvent);
		}
		foreach(string strEventName in ActivateEventNames)
		{
			m_rEventComponent.AddEventHandler(strEventName, HandleActivationEvent);
		}
	}
	
	/// \brief  Called when the component is disabled
	void OnDisable() 
	{	
		// Remove the appear event handler
		foreach(string strEventName in DeactivateEventNames)
		{
			m_rEventComponent.RemoveEventHandler(strEventName, HandleDeactivationEvent);
		}
		foreach(string strEventName in ActivateEventNames)
		{
			m_rEventComponent.RemoveEventHandler(strEventName, HandleActivationEvent);
		}
	}
	
	/// \brief  Handle the deactivation event
	void HandleDeactivationEvent(Object m_rEvent)
	{
		DeactivateComponents();
	}
	
	/// \brief  Handle the activation event
	void HandleActivationEvent(Object m_rEvent)
	{
		ActivateComponents();
	}
	
	/// \brief  Deactivat the components
	void DeactivateComponents()
	{
		switch(EnableDisableMode)
		{
			case EEnableDisableMode.Enable_Disable:
			{
				// Disable all the controlled components
				foreach(MonoBehaviour rComponent in ControlledComponents)
				{
					rComponent.enabled = false;
				}
			}
			break;
			
			case EEnableDisableMode.Disable_ReEnable:
			{
				// Disable the controlled component that are enabled
				// and save it on the to re enable list
				foreach(MonoBehaviour rComponent in ControlledComponents)
				{
					if(rComponent.enabled)
					{
						rComponent.enabled = false;
						m_rToReEnableComponents.Add(rComponent);
					}
				}
			}
			break;
			
			case EEnableDisableMode.Enable_ReDisable:
			{
				// Disable the controlled component that were previously enable by this component
				foreach(MonoBehaviour rComponent in m_rToReDisableComponents)
				{
					rComponent.enabled = false;
				}
				m_rToReDisableComponents.Clear();
			}
			break;
		}
	}

	/// \brief  Activate the components
	void ActivateComponents()
	{
		switch(EnableDisableMode)
		{
			case EEnableDisableMode.Enable_Disable:
			{
				// Enable all the controlled components
				foreach(MonoBehaviour rComponent in ControlledComponents)
				{
					rComponent.enabled = true;
				}
			}
			break;
			
			case EEnableDisableMode.Disable_ReEnable:
			{
				// Enable the controlled component that were previously disable by this component
				foreach(MonoBehaviour rComponent in m_rToReEnableComponents)
				{
					rComponent.enabled = true;
				}
				m_rToReEnableComponents.Clear();
			}
			break;
			
			case EEnableDisableMode.Enable_ReDisable:
			{
				// Disable the controlled component that are enabled
				// and save it on the to re disable list
				foreach(MonoBehaviour rComponent in ControlledComponents)
				{
					if(rComponent.enabled == false)
					{
						rComponent.enabled = true;
						m_rToReDisableComponents.Add(rComponent);
					}
				}
			}
			break;
		}
	}
}
